home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
emac16ds.zip
/
EXECUTE.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-06-13
|
11KB
|
493 lines
;History:134,1
;Sun Mar 26 20:54:16 1989 remove reference to textseg.
;03-27-88 14:27:20 remove execute_filter code.
;03-13-88 12:26:39 remove the execute filter stuff.
stderr equ 1
.xlist
include memory.def
data segment byte public
extrn phd_seg: word
fcb_struc struc
fcb_drive db 0
fcb_fname db ' '
fcb_ext db ' '
fcb_curblk dw 0
fcb_recsz dw 0
fcb_filsz dw 0,0
fcb_date dw 0
fcb_time dw 0
fcb_res dd ?,?
fcb_currec db 0
fcb_ranrec dw 0,0
fcb_struc ends
segofs struc
offs dw ?
segm dw ?
segofs ends
emmp struc ; xms extended memory manager parms
bcountl dw ? ; byte count
bcounth dw ?
shandle dw ? ; emm handle (source)
soffset dd ? ; offset into source block
dhandle dw ? ; emm handle (destination)
doffset dd ? ; offset into destination block
emmp ends
echo_flag dw ? ;echo STDOUT/STDERR output during spawn
reload_routine dd ? ;pointer to reload routine in phd_seg
swap_sizel dw ? ;temporary save area for swap data size
swap_sizeh dw ?
emm_parm emmp <> ;emm parameter block
xms dd ? ;emm driver entry point
block_psize dw ?
data ends
fn_size equ 64 ;size of file name to save in reload data
reload segment at 0 ;the order of the data in this segment is
r_base label byte ;critically dependent on the format of
;corresponding data in data and code segments
;modify with caution.
org 100h
r_ss dw ? ;stack segment
r_sp dw ? ;stack pointer
r_parms dw 7 dup (?) ;exec parameter block
r_emmp emmp <> ;xms parm block
r_xms segofs <> ;emm driver entry point
r_psize dw ? ;allocated memory block size in paragraphs
r_dvec segofs <> ;DOS interrupt vector
db 300 dup (?) ;temporary stack area
r_stack dw ? ;top of temporary stack
r_fname db fn_size dup (?) ;file name to execute
r_subr label byte ;reloader subroutine
r_size equ $-r_ss ;reloader code and data size
r_offset equ $-r_base
reload ends
code segment byte public
;all the routines in this segment are entered with ds=data, es=data
assume cs:code, ds:data, es:data, ss:data
;the following externs are in 'buffers'
extrn compact_buffers: near
extrn uncompact_buffers: near
;the following externs are in 'memory'
extrn read_mark: near
extrn del_to_mark: near
extrn insert_string$: near
;the following externs are in 'redisplay'
extrn redisplay: near
extrn paint_screen: near
extrn init_entry: near
extrn uninit_exit: near
extrn abort_fatal: near ;fatal error handler
our_sp dw ?
our_ss dw ?
parameters dw 0
dw 80h, ?
dw 5ch, ?
dw 6ch, ?
copy_to_dioa:
;enter with si, cx->command.
;exit with cs:phd_dioa set to the string.
push es
mov es,phd_seg ;copy the command to phd_dioa+1
mov di,80h+1
if 0
mov ax,3700h ;get the switch char.
int 21h
mov al,dl
stosb
mov al,'C' ;store -C or /C.
stosb
endif
rep movsb
mov al,CR ;store the terminating CR.
stosb
sub di,80h+1+1 ;don't count the CR.
mov ax,di
mov es:[80h],al ;store the count.
pop es ;restore es.
ret
public execute_program
execute_program:
;enter with si, cx->path of filter to execute, di ->null terminated filename.
; ax = echo STDOUT/STDERR output flag
;exit with ax=return result.
; mov echo_flag,ax
mov echo_flag,0
push di
call copy_to_dioa
pop di
call actually_execute
ret
actually_execute:
;enter with di -> filename, cs:phd_dioa = arguments.
push di
call uninit_exit
pop di
push ds
push es
push di
call compact_buffers ;make room for the program.
pop di
mov dx,phd_seg ;subtract off the allocated segment.
sub bx,dx
mov es,dx ;get es=allocated segment.
assume es:nothing
mov ah,4ah ;reduce ourself in size.
int 21h
mov our_sp,sp ;remember our stack.
mov our_ss,ss
mov ds,phd_seg ;move ds first because we need ds.
assume ds:nothing
mov es,phd_seg
assume es:nothing
mov dx,di ;set up to execute the program.
mov ax,2901h ;parse fcb1.
mov si,81h ;->phd_sdioa.
mov di,5ch ;->phd_fcb1
int 21h
mov ax,2901h ;parse fcb2.
mov di,6ch ;->phd_fcb2.
int 21h
push ss ;ss:dx -> filename to execute.
pop ds
assume ds:data
push cs
pop es
assume es:code
call xms_execute ;swap out to ems, then execute, if
jnc actually_execute_2 ; possible
;otherwise continue with normal exec
mov bx,offset parameters
mov ax,phd_seg
mov es:[bx]+4,ax ;use original phd parameters.
mov es:[bx]+8,ax
mov es:[bx]+12,ax
mov ax,4b00h
int 21h
jc actually_execute_1
xor ax,ax ;make sure ax is zero if no errors.
actually_execute_1:
cli ;get our stack back.
mov ss,cs:our_ss
mov sp,cs:our_sp
sti
actually_execute_2:
push ax
mov bx,0ffffh ;now grab all of memory again.
mov es,phd_seg
mov ah,4ah ;see how much is available.
int 21h
mov ah,4ah ;grab all of it.
int 21h
push cs ;reset the fatal error address.
pop ds
mov dx,offset abort_fatal
mov ax,2524h
int 21h
mov ax,33h*256+1 ;turn break checking back off.
mov dl,0 ; in case someone turned it on.
int 21h
pop ax
pop es
pop ds
assume ds:data, es:data
push ax
call uncompact_buffers ;make room for the text again.
call init_entry
call paint_screen
pop ax
ret
.286
assume cs:code, ds:data,es:nothing
xms_execute:
; enter with dx -> file name to execute, bx - number of paragraphs allocated
mov ax,4300h ;if xms driver not installed
int 2fh ; (himem.sys, et.al.)
cmp al,80h
je xms_execute_1
stc ; return error indication to continue
ret ; exec without swapping
xms_execute_1:
push bx
push es
mov ax,4310h ;fetch emm driver entry point
int 2fh
mov xms.offs,bx
mov xms.segm,es
pop es
pop bx
mov block_psize,bx ;save allocated memory size
mov di,dx ;save file name pointer
sub bx,16 ;subtract psp size from paragraph count
mov ax,bx ;compute size of area to be swapped
mov dl,ah
shr dl,4
xor dh,dh
shl ax,4
mov swap_sizel,ax
mov swap_sizeh,dx
mov dx,bx ;allocate xms memory
add dx,63 ;round paragraph count up to multiple of 1024
shr dx,6
mov ah,09h
call xms
cmp ax,1 ;if error on allocation
je xms_execute_2
stc ; abort swap proceedure
ret
xms_execute_2: ;endif
;swap out the memory used by reload routine
mov emm_parm.bcountl,reload_swap_size
mov emm_parm.bcounth,0
mov emm_parm.dhandle,dx
mov emm_parm.doffset.offs,0
mov emm_parm.doffset.segm,0
mov emm_parm.shandle,0
mov emm_parm.soffset.offs,100h
mov es,phd_seg
assume es:reload
mov emm_parm.soffset.segm,es
mov si,offset data:emm_parm
mov ah,0bh
call xms
cmp ax,1 ;if error on swap out
je xms_execute_3
stc ; abort swap proceedure
ret
xms_execute_3: ;endif
;copy needed data to reload data area
mov si,di ; first the executable file name
mov di,offset reload:r_fname
mov cx,fn_size
rep movsb
push ds ; then the DOS exec block
mov ax,cs
mov ds,ax
mov si,offset code:parameters
mov di,offset reload:r_parms
mov cx,7
rep movsw
pop ds ; followed by the XMS move parm block
mov si,offset data:emm_parm
mov cx,11
rep movsw
;copy reload subroutine
push ds
mov ds,ax
mov di,offset reload:r_subr
mov si,offset code:reload_subr
mov cx,reload_size
rep movsb
pop ds
;adjust reload xms reload parameters to save
;all but resident subroutine and data
mov ax,swap_sizel
mov dx,swap_sizeh
sub ax,reload_swap_size
sbb dx,0
mov r_emmp.bcountl,ax
mov r_emmp.bcounth,dx
add r_emmp.doffset.offs,reload_swap_size
mov r_emmp.soffset.offs,reload_swap_size+100h
cmp echo_flag,0 ;if echo flag set
je xms_execute_4
push es
mov ax,3521h ; hook us into the DOS interrupt chain
int 21h
mov ax,es
pop es
mov word ptr r_dvec,bx
mov word ptr r_dvec+2,ax
mov ax,2521h
mov dx,dv_offset
push es
pop ds
int 21h
push ss
pop ds
xms_execute_4:
;call the resident subroutine
mov ax,offset reload:r_subr
mov reload_routine.offs,ax
mov reload_routine.segm,es
call reload_routine
push ax ;save exec return code
cmp echo_flag,0 ;if echo flag set
je xms_execute_5
mov ax,2521h ; remove us from DOS interrupt chain
lds dx,r_dvec
int 21h
push ss
pop ds
xms_execute_5:
;restore code overlaid by resident s & d
mov ax,emm_parm.dhandle
xchg ax,emm_parm.shandle
mov emm_parm.dhandle,ax
mov ax,emm_parm.doffset.offs
xchg ax,emm_parm.soffset.offs
mov emm_parm.doffset.offs,ax
mov ax,emm_parm.doffset.segm
xchg ax,emm_parm.soffset.segm
mov emm_parm.doffset.segm,ax
mov si,offset data:emm_parm
mov ah,0bh
call xms
;release extended memory
mov dx,emm_parm.shandle
mov ah,0ah
call xms
pop ax ;restore exec return code
clc ;signal sucessful exec and reload
ret
assume cs:code, ds:data, es:reload
reload_subr: ;resident reload subroutine gets copied to
; low code space while swapped out
push ds
mov r_sp,sp ;remember our stack.
mov r_ss,ss
mov bx,cs ;switch to temporary stack
mov ss,bx
mov sp,offset reload:r_stack
mov ds,bx ;establish addressability to phd segment
assume ds:reload
;swap out primary code and data area
mov si,offset reload:r_emmp
mov ah,0bh
call r_xms
;free swapped out code and data
mov bx,reload_swap_size+100h
shr bx,4
mov ah,4ah
int 21h
mov dx,offset reload:r_fname
mov bx,offset reload:r_parms
mov [bx]+4,ds ;use original phd parameters.
mov [bx]+8,ds
mov [bx]+12,ds
mov ax,4b00h
int 21h
jc xms_execute_6
xor ax,ax ;make sure ax is zero if no errors.
xms_execute_6:
mov bx,cs ;restore temporary stack
mov ss,bx
mov sp,offset reload:r_stack
mov es,bx ;restore data segment registers
mov ds,bx
mov bx,r_psize ;reallocate swapped memory
mov ah,4ah
int 21h
;restore primary swapped out code and data
mov ax,r_emmp.dhandle
xchg ax,r_emmp.shandle
mov r_emmp.dhandle,ax
mov ax,r_emmp.doffset.offs
xchg ax,r_emmp.soffset.offs
mov r_emmp.doffset.offs,ax
mov ax,r_emmp.doffset.segm
xchg ax,r_emmp.soffset.segm
mov r_emmp.doffset.segm,ax
mov si,offset reload:r_emmp
mov ah,0bh
call r_xms
mov ss,cs:r_ss ;restore primary stack
mov sp,cs:r_sp
pop ds
retf
assume cs:code, ds:nothing, es:nothing
dv_offset equ r_offset + $ - reload_subr
dos_vect:
cmp ah,40h
jne dv_exit
cmp bx,2
jg dv_exit
push si
push cx
push bx
push ax
mov si,dx
xms_execute_7: lodsb
; int 29h
mov ah,0eh
int 10h
loop xms_execute_7
pop ax
pop bx
pop cx
pop si
dv_exit:
jmp cs:r_dvec
reload_size equ $-reload_subr
reload_swap_size equ (r_size + reload_size + 1) and 0fffeh
code ends
end